﻿using System;

namespace 面向对象复习
{


    //struct vextor2 
    //{
    //    public int x, y;

    //    public vextor2(int x,int y) //------->结构体也可以使用构造函数
    //    {
    //        this.x = x;
    //        this.y = y;
    //    }
    //}

    #region 玩家类
    class player 
    {
        string name;
        int atk;
        int def;
        int hp;
        int Maxhp;
        weapon weapon;
        Item[] backage;//数组————背包
        //动态增加的数组



        ////写一个方法把信息暴露出去
        //public player GetPlayInfo() //因为是暴露玩家的信息，所以直接用player了
        //{
        //    player playerinfo= new player(this.name,this.atk,this.def,this.hp,this.Maxhp);
        //    playerinfo.GetWeapon(this.weapon);//装备武器


        //    return playerinfo;
        //    //返还回去的信息值是一致的
        //}



        //只读取，不能更改
        public string GetName()
        {
            return name;
        }

        public int GetAtk()
        {
            return atk;
        }

        public int GetDef()
        {
            return def;
        }
        public int GetHp()
        {
            return hp;
        }
        public int GetMaxHp()
        {
            return Maxhp;
        }

        public weapon GetWeapon()
        {
            return weapon;
        }




        //构造函数
        public player(string name,int atk, int def, int hp,int Maxhp) 
        {
            this.name = name;
            this.atk = atk;
            this.def = def;
            this.hp = hp;
            this.Maxhp = Maxhp;
           
        }


        //攻击方法：
        public void Attack(Monster monster)
        {
            //攻击怪物
            //在玩家这里直接调用怪物的受伤方法
            monster.OnDamage(this.atk);//传入自己的攻击力
        }

        //装备武器
        public void GetWeapon(weapon wuqi) 
        {
            this.weapon = wuqi;
            this.atk += weapon.atkAdd;
        }

        //同样攻击怪物的方法
        public void OnDamage(int atk)
        {
            this.atk = atk;
            //伤害公式
            //伤害=（攻击-自身防御力） <=0?1:攻击-自身防御力
            int damage = atk - this.def;
            damage = (damage <= 0) ? 1 : damage;//判断是否破防，没破防就掉1点血
            this.hp -= damage;
        }
        
        //斩击
        public void Deadchop(Monster m)
        {
            int attack = this.atk * 2;
            m.OnDamage(attack);//重新调入这个函数
        }
    }

    #endregion






    #region 武器类
    class weapon 
    {
         public string name;
         public int naijiudu;//耐久度
         public int Maxnaijiudu;//最大耐久度
         public int atkAdd;//攻击加成
        
           

        //构造函数
        public weapon(string name, int naijiudu, int Maxnaijiudu, int atkAdd)
        {
            this.name = name;
            this.naijiudu = naijiudu;
            this.Maxnaijiudu = Maxnaijiudu;
            this.atkAdd = atkAdd;
        }


    }

    #endregion

    #region 背包
    class Item 
    {
    }




    #endregion


    #region 怪物类
    class Monster 
    {
        public string name;
        public int atk;
        public int def;//防御
        public int hp;
        public int Maxhp;







        //构造函数
        public Monster(string name, int atk, int def, int hp,int Maxhp)
        {
            this.name = name;
            this.atk = atk;
            this.def = def;
            this.hp = hp;
            this.Maxhp = Maxhp;
        }


        //两边都是不公开，这里写一个接口
        public void OnDamage(int ak) 
        {
            this.atk = atk;
            //伤害公式
            //伤害=（攻击-自身防御力） <=0?1:攻击-自身防御力
            int damage = atk - this.def;
            damage = (damage <= 0) ? 1 : damage;//判断是否破防，没破防就掉1点血
            this.hp -= damage;
        }



        //攻击玩家方法---玩家受伤方法
        public void Addack(player p) 
        {
            p.OnDamage(this.atk);//玩家受伤
        }

    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            #region  面向对象知识点复习
            //面向对象----万物皆对象
            //类 
            //   有相同属性，相同行为的对象们抽象出来的横板，叫做类
            //class 类名 
            //        {
            //              字段;
            //              属性；
            //              方法；
            //        }
            //类名 对象名 = new 类名();

            //调用：对象名.成员名，dot语法可以调用对象公开的成员

            //对象：有生命周期----由生到死
            //生(构造函数)-------
            //                          访问修饰符  类名(形参列表)
            //                          {
            //                              初始化
            //                          }
            //构造函数可以重载
            //this关键字两个作用   ————————》1.指代自身实例对象
            //this关键字两个作用   ————————》2.指代自身构造函数  在参数列表后用冒号连接

            //活着（有变量直接或间接指向这个对象，如果没有，则垃圾回收机制回收）

            //析构函数
            //类名  ()  {}
            #endregion


            //vextor2 dir = new vextor2(1,3);
            //结构体也有构造函数
            //也可以重载
            //1.只能重载有参构造函数
            //2.在构造函数中必须对每个属性赋值 this.x=x；

            #region 练习

            //声明一个玩家类，有攻击力，防御力，血量，武器，行为攻击，装备武器
            //声明一个武器类，有耐久度，有攻击加成
            //声明一个怪物类，有攻击力，防御力，血量，武器，行为有攻击

            //实例化一把武器，让玩家装备，实例化一个怪物
            //让玩家和怪物互殴，要有角色信息显示


            //攻击力写随机数
            Random r = new Random();
            //this.name, this.atk, this.def, this.hp, this.Maxhp
            player p1 = new player("footman",r.Next(300,500),r.Next(300,400),1000,1000);

            //string name, int naijiudu, int Maxnaijiudu, int atkAdd
            weapon w = new weapon("斧头", 100, 100, 500);

            //装备给玩家
            p1.GetWeapon(w);

            //this.name, this.atk, this.def, this.hp
            Monster m1 = new Monster("史莱姆",r.Next(150, 200), r.Next(100, 200), 2000,2000);


            //回合攻击
            while (true)
            {

                 Showinfo(p1, m1);

                //添加攻击选择
                Console.WriteLine("请选择攻击方式：1.普通攻击\t 2.致命打击");
                //监听玩家输入
                char input = Console.ReadKey(true).KeyChar;
                if (input == '1')
                {
                    //普攻
                    p1.Attack(m1);
                    Console.SetCursorPosition(0, 7);
                    Console.WriteLine("{0}攻击了{1}", p1.GetName(), m1.name);
                }
                else 
                {
                    p1.Deadchop(m1);
                    Console.SetCursorPosition(0, 7);
                    Console.WriteLine("{0}使用了致命打击对{1}", p1.GetName(), m1.name);
                }




                Showinfo(p1, m1);
                
                //每一个回合卡一下案件

                Console.ReadKey(true);
                m1.Addack(p1);


                Console.SetCursorPosition(0, 7);
                Console.WriteLine("{0}攻击了{1}", m1.name, p1.GetName());
                Showinfo(p1, m1);

                //每一个回合卡一下案件
                Console.ReadKey(true);
            }



            //调用
            Showinfo(p1,m1);

            #endregion


        }

        //封装
        static void Showinfo(player p1, Monster m1) 
        {
            //把信息打印在固定地方
            //玩家
            Console.SetCursorPosition(0, 0);

            Console.WriteLine("{0}:\t HP:{1}/{2}\t ATK:{3}\t DEF:{4}\t Weapon:{5}"
                , p1.GetName(),
                p1.GetHp(),
                p1.GetMaxHp(),
                p1.GetAtk(),
                p1.GetDef(),
                p1.GetWeapon().name);


            //怪物
            Console.SetCursorPosition(0, 15);
            Console.WriteLine("{0}:\t HP:HP:{1}/{2}\t ATK:{3}\t DEF:{4}\t", m1.name, m1.hp, m1.Maxhp, m1.atk, m1.def);

        }
    }
}
